home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload Trio 2 / Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO / dir27 / calctool.zip / X11.C < prev    next >
C/C++ Source or Header  |  1994-01-23  |  15KB  |  541 lines

  1.  
  2. /*  @(#)x11.c 1.14 89/12/21
  3.  *
  4.  *  These are the X11 dependent graphics routines used by calctool.
  5.  *
  6.  *  Copyright (c) Rich Burridge.
  7.  *                Sun Microsystems, Australia - All rights reserved.
  8.  *
  9.  *  Permission is given to distribute these sources, as long as the
  10.  *  copyright messages are not removed, and no monies are exchanged.
  11.  *
  12.  *  No responsibility is taken for any errors or inaccuracies inherent
  13.  *  either to the comments or the code of this program, but if
  14.  *  reported to me then an attempt will be made to fix them.
  15.  */
  16.  
  17. #include <stdio.h>
  18. #include "calctool.h"
  19. #include "color.h"
  20. #include "extern.h"
  21. #include <X11/Xlib.h>
  22. #include <X11/Xutil.h>
  23. #include <X11/Xatom.h>
  24. #include <X11/cursorfont.h>
  25. #include <X11/keysym.h>
  26.  
  27. #define  XGETSIZEHINTS  (void) XGetSizeHints
  28.  
  29. #define  BIGFONT               "helvetica-bold-14"
  30. #define  DEFFONT               "fixed"
  31. #define  NORMALFONT            "fixed"
  32. #define  SMALLFONT             "6x10"
  33.  
  34. #define  CALCTOOL_BORDER_WIDTH  2
  35.  
  36. #define  FRAME_MASK  (ButtonPressMask | ButtonReleaseMask | KeyPressMask | \
  37.                       EnterWindowMask | LeaveWindowMask | ExposureMask)
  38.  
  39. short help_cursor_array[16] = {
  40. #include "help.cursor"
  41. } ;
  42.  
  43. short icon_image[] = {
  44. #include "calctool.icon"
  45. } ;
  46.  
  47. short cicon_image[] = {
  48. #include "calctool.ico"
  49. } ;
  50.  
  51. Atom protocol_atom, kill_atom ;
  52. Cursor help_cursor, main_cursor ;
  53. Display *dpy ;
  54. GC gc ;
  55. Pixmap calctool_icon, help_pixmap ;
  56. Pixmap load_icon() ;
  57. Window frame, rframe ;
  58. XColor BGcolor, FGcolor, current_col ;
  59. XEvent event ;
  60. XFontStruct *bfont, *font, *nfont, *sfont ;
  61. XGCValues gc_val ;
  62. XSizeHints size ;
  63. XWMHints wm_hints ;
  64.  
  65. unsigned long gc_mask ;
  66. int screen ;
  67. unsigned int scr_depth ;
  68. unsigned long backgnd, foregnd ;
  69. unsigned long palette[CALC_COLORSIZE] ;
  70.  
  71.  
  72. clear_canvas(ctype, color)
  73. enum can_type ctype ;
  74. int color ;
  75. {
  76.   int x, y ;
  77.   unsigned int width, height, bwidth, depth ;
  78.   Window root, window ;
  79.  
  80.        if (ctype == KEYCANVAS) window = frame ;
  81.   else if (ctype == REGCANVAS) window = rframe ;
  82.   XGetGeometry(dpy, window, &root, &x, &y, &width, &height, &bwidth, &depth) ;
  83.   if (iscolor) gc_val.foreground = palette[color] ;
  84.   else
  85.     {
  86.       if (color == WHITE) gc_val.foreground = backgnd ;
  87.       else gc_val.foreground = foregnd ;
  88.     }
  89.   gc_val.function = GXcopy ;
  90.   XChangeGC(dpy, gc, GCForeground | GCFunction, &gc_val) ;
  91.   XFillRectangle(dpy, window, gc, x, y, width, height) ;
  92. }
  93.  
  94.  
  95. close_frame()
  96. {
  97.   XEvent event ;
  98.  
  99.   event.xclient.type = ClientMessage ;
  100.   event.xclient.display = dpy ;
  101.   event.xclient.window = frame ;
  102.   event.xclient.message_type = XInternAtom(dpy, "WM_CHANGE_STATE", False) ;
  103.   event.xclient.format = 32 ;
  104.   event.xclient.data.l[0] = IconicState ;
  105.   XSendEvent(dpy, DefaultRootWindow(dpy), False,
  106.           SubstructureRedirectMask | SubstructureNotifyMask, &event) ;
  107.   XFlush(dpy) ;
  108. }
  109.  
  110.  
  111. color_area(x, y, width, height, color)
  112. int x, y, width, height, color ;
  113. {
  114.   if (iscolor) gc_val.foreground = palette[color] ;
  115.   else
  116.     {
  117.       if (color == WHITE) gc_val.foreground = backgnd ;
  118.       else gc_val.foreground = foregnd ;
  119.     }
  120.   gc_val.function = GXcopy ;
  121.   XChangeGC(dpy, gc, GCForeground | GCFunction, &gc_val) ;
  122.   XFillRectangle(dpy, frame, gc, x, y,
  123.                  (unsigned int) width, (unsigned int) height) ;
  124. }
  125.  
  126.  
  127. create_menu(mtype)    /* Create popup menu for right button press. */
  128. enum menu_type mtype ;
  129. {
  130. }
  131.  
  132.  
  133. destroy_frame()
  134. {
  135.   XDestroyWindow(dpy, frame) ;
  136.   XDestroyWindow(dpy, rframe) ;
  137.   exit(0) ;
  138. }
  139.  
  140.  
  141. do_menu(mtype)      /* Popup appropriate menu and get value. */
  142. enum menu_type mtype ;
  143. {
  144. }
  145.  
  146.  
  147. drawline(x1, y1, x2, y2)
  148. int x1, y1, x2, y2 ;
  149. {
  150.   if (iscolor) gc_val.foreground = palette[BLACK] ;
  151.   else gc_val.foreground = foregnd ;
  152.   gc_val.function = GXcopy ;
  153.   XChangeGC(dpy, gc, GCForeground | GCFunction, &gc_val) ;
  154.   XDrawLine(dpy, frame, gc, x1, y1, x2, y2) ;
  155. }
  156.  
  157.  
  158. draw_regs()
  159. {
  160.   XMapWindow(dpy, rframe) ;
  161. }
  162.  
  163.  
  164. drawtext(x, y, ctype, fontno, color, str)
  165. enum font_type fontno ;
  166. enum can_type ctype ;
  167. int x, y, color ;
  168. char *str ;
  169. {
  170.   Window window ;
  171.  
  172.        if (fontno == SFONT) font = sfont ;
  173.   else if (fontno == NFONT) font = nfont ;
  174.   else if (fontno == BFONT) font = bfont ;
  175.        if (ctype == KEYCANVAS) window = frame ;
  176.   else if (ctype == REGCANVAS) window = rframe ;
  177.  
  178.   if (ctype == KEYCANVAS && y == items[(int) DISPLAYITEM].y) x += 100 ;
  179.   if (iscolor) gc_val.foreground = palette[color] ;
  180.   else
  181.     {
  182.       if (color == WHITE) gc_val.foreground = backgnd ;
  183.       else gc_val.foreground = foregnd ;
  184.     }
  185.   gc_val.font = font->fid ;
  186.   gc_val.function = GXcopy ;
  187.   XChangeGC(dpy, gc, GCFont | GCForeground | GCFunction, &gc_val) ;
  188.   XDrawString(dpy, window, gc, x, y, str, strlen(str)) ;
  189. }
  190.  
  191.  
  192. get_display()         /* GET function key was pressed. */
  193. {
  194. }
  195.  
  196.  
  197. XFontStruct *
  198. get_font(name)
  199. char *name ;
  200. {
  201.   XFontStruct *font ;
  202.  
  203.   if (!(font = XLoadQueryFont(dpy, name)))
  204.     if (!(font = XLoadQueryFont(dpy, DEFFONT)))
  205.       {
  206.         perror("couldn't get the default font.") ;
  207.         exit(1) ;
  208.       }
  209.   return(font) ;
  210. }
  211.  
  212.  
  213. get_next_event()
  214. {
  215.   XClientMessageEvent *ev ;
  216.   XKeyPressedEvent *key_event ;
  217.   KeySym keysym ;
  218.   char chs[2] ;
  219.  
  220.   if (!XCheckMaskEvent(dpy, ExposureMask, &event))
  221.     XNextEvent(dpy, &event) ;
  222.  
  223.   switch (event.type)
  224.     {
  225.       case ClientMessage    : /* Catch ICCCM kill from WM. */
  226.  
  227.                               ev = (XClientMessageEvent *) &event ;
  228.                               if (ev->message_type == protocol_atom &&
  229.                                   ev->data.l[0] == kill_atom)
  230.                                 exit(0) ;
  231.                               return(LASTEVENTPLUSONE) ;
  232.  
  233.       case Expose           : return(process_expose(&event)) ;
  234.  
  235.       case EnterNotify      : return(ENTER_WINDOW) ;
  236.  
  237.       case LeaveNotify      : return(EXIT_WINDOW) ;
  238.  
  239.       case KeyPress         : key_event = (XKeyPressedEvent *) &event ;
  240.                               curx = key_event->x ;
  241.                               cury = key_event->y ;
  242.                               (void) XLookupString(key_event, chs, 1,
  243.                                                    &keysym,
  244.                                                    (XComposeStatus *) NULL) ;
  245.                               if (keysym == XK_Shift_L ||
  246.                                   keysym == XK_Shift_R) break ;
  247.                               cur_ch = chs[0] ;
  248.                               return(KEYBOARD) ;
  249.  
  250.       case ButtonPress      : curx = event.xbutton.x ;
  251.                               cury = event.xbutton.y ;
  252.                               if (event.xbutton.button == Button1)
  253.                                 return(LEFT_DOWN) ;
  254.                               else if (event.xbutton.button == Button2)
  255.                                 return(MIDDLE_DOWN) ;
  256.                               else if (event.xbutton.button == Button3)
  257.                                 return(RIGHT_DOWN) ;
  258.  
  259.       case ButtonRelease    : curx = event.xbutton.x ;
  260.                               cury = event.xbutton.y ;
  261.                               if (event.xbutton.button == Button1)
  262.                                 return(LEFT_UP) ;
  263.                               else if (event.xbutton.button == Button2)
  264.                                 return(MIDDLE_UP) ;
  265.                               else if (event.xbutton.button == Button3)
  266.                                 return(RIGHT_UP) ;
  267.  
  268.       default               : return(LASTEVENTPLUSONE) ;
  269.    }
  270. /*NOTREACHED*/
  271. }
  272.  
  273.  
  274. handle_selection()
  275. {
  276. }
  277.  
  278.  
  279. init_fonts()
  280. {
  281.   bfont = get_font(BIGFONT) ;
  282.   nfont = get_font(NORMALFONT) ;
  283.   nfont_width = 6 ;
  284.   sfont = get_font(SMALLFONT) ;
  285. }
  286.  
  287.  
  288. init_ws_type()
  289. {
  290.   char *tmpGeometry;
  291.  
  292.   if ((dpy = XOpenDisplay(x11_display)) == NULL)
  293.     {
  294.       FPRINTF(stderr,"%s: Couldn't open display %s\n", progname,
  295.               (getenv ("DISPLAY") ? getenv("DISPLAY") : x11_display)) ;
  296.       exit(1) ;
  297.     }
  298.  
  299.   screen = DefaultScreen(dpy) ;
  300.  
  301.   if ( *geometry == '\0')
  302.     tmpGeometry = XGetDefault(dpy, progname, "Geometry");
  303.  
  304.   if (tmpGeometry != NULL )
  305.     STRCPY(geometry, tmpGeometry);
  306.  
  307.   foregnd = BlackPixel(dpy, screen) ;
  308.   backgnd = WhitePixel(dpy, screen) ;
  309.   scr_depth = DefaultDepth(dpy, screen) ;
  310.   gtype = X11 ;
  311.   return 0 ;
  312. }
  313.  
  314.  
  315. load_colors()      /* Create and load calctool color map. */
  316. {
  317.   u_char red[CALC_COLORSIZE], green[CALC_COLORSIZE], blue[CALC_COLORSIZE] ;
  318.   int i, numcolors ;
  319.  
  320.   iscolor = 0 ;
  321.   if (DisplayCells(dpy, screen) > 2)
  322.     {
  323.       calc_colorsetup(red, green, blue) ;
  324.       iscolor = 1 ;
  325.       numcolors = 0 ;
  326.       for (i = 0; i < CALC_COLORSIZE; i++)
  327.         {
  328.           current_col.flags = DoRed | DoGreen | DoBlue ;
  329.           current_col.red = (unsigned short) (red[i] << 8) ;
  330.           current_col.green = (unsigned short) (green[i] << 8) ;
  331.           current_col.blue = (unsigned short) (blue[i] << 8) ;
  332.           if (XAllocColor(dpy, DefaultColormap(dpy, screen), ¤t_col) == True)
  333.             palette[numcolors++] = current_col.pixel ;
  334.         }
  335.       if (numcolors < 2)
  336.         {
  337.           FPRINTF(stderr, "%s: cannot allocate colors.\n", progname) ;
  338.           exit(1) ;
  339.         }
  340.     }
  341. }
  342.  
  343.  
  344. Cursor
  345. load_cursor(sbuf)
  346. short sbuf[16] ;
  347. {
  348.   char cbuf[32] ;
  349.   int i ;
  350.  
  351.   for (i = 0; i < 16; i++)
  352.     {
  353.       cbuf[i*2+0] = revtable[(sbuf[i] >> 8) & 0xFF] ;
  354.       cbuf[i*2+1] = revtable[sbuf[i] & 0xFF] ;
  355.     }
  356.   help_pixmap = XCreatePixmapFromBitmapData(dpy, RootWindow(dpy, screen), cbuf,
  357.                                      16, 16, foregnd, backgnd, 1) ;
  358.   return(XCreatePixmapCursor(dpy, help_pixmap, help_pixmap,
  359.                                     &FGcolor, &BGcolor, 0, 0)) ;
  360. }
  361.  
  362.  
  363. Pixmap
  364. load_icon(sbuf)
  365. short sbuf[] ;
  366. {
  367.   GC pix_gc ;
  368.   Pixmap pixmap ;
  369.   XImage *image ;
  370.   char cbuf[512*8] ;
  371.   int i ;
  372.  
  373.   if (iscolor)
  374.     {
  375.       for (i = 0; i < (256*8); i++)
  376.         {
  377.           cbuf[i*2+0] = palette[(sbuf[i] >> 8) & 0xFF] ;
  378.           cbuf[i*2+1] = palette[sbuf[i] & 0xFF] ;
  379.         }
  380.       pix_gc = DefaultGC(dpy, screen) ;
  381.       image = XCreateImage(dpy, DefaultVisual(dpy, screen),
  382.                            scr_depth, ZPixmap, 0, cbuf, 64, 64, 8, 64) ;
  383.       pixmap = XCreatePixmap(dpy, RootWindow(dpy, screen),
  384.                              ICONWIDTH, (unsigned) image->height, scr_depth) ;
  385.       XPutImage(dpy, pixmap, pix_gc, image, 0, 0, 0, 0,
  386.                 ICONWIDTH, (unsigned) image->height) ;
  387.     }
  388.   else
  389.     {
  390.       for (i = 0; i < 256; i++)
  391.         {
  392.           cbuf[i*2+0] = revtable[(sbuf[i] >> 8) & 0xFF] ;
  393.           cbuf[i*2+1] = revtable[sbuf[i] & 0xFF] ;
  394.         }
  395.       pixmap = XCreatePixmapFromBitmapData(dpy, RootWindow(dpy, screen), cbuf,
  396.                                      64, 64, foregnd, backgnd, scr_depth) ;
  397.     }
  398.   return(pixmap) ;
  399. }
  400.  
  401.  
  402. make_frames(argc, argv)
  403. int argc ;
  404. char *argv[] ;
  405. {
  406.   unsigned int h, w ;       /* Window dimensions. */
  407.   int flags ;
  408.   int x, y ;                /* Window position. */
  409.            
  410.   load_colors() ;
  411.   if (iscolor) calctool_icon = load_icon(cicon_image) ;
  412.   else calctool_icon = load_icon(icon_image) ;
  413.  
  414.   size.flags = PMinSize | PMaxSize | PPosition | PSize ;
  415.   size.x = 0 ;
  416.   size.y = 0 ;
  417.   size.max_width = size.min_width = size.width = TWIDTH ;
  418.   size.max_height = size.min_height = size.height = THEIGHT + DISPLAY ;
  419.  
  420.   if (strlen(geometry))
  421.     {
  422.       flags = XParseGeometry(geometry, &x, &y, &w, &h) ;
  423.       if (XValue & flags)
  424.         {
  425.           if (XNegative & flags)
  426.             x = DisplayWidth(dpy, screen) + x - size.width ;
  427.             size.flags |= USPosition ;
  428.             size.x = x ;
  429.         }
  430.       if (YValue & flags)
  431.         {
  432.           if (YNegative & flags)
  433.             y = DisplayHeight(dpy, screen) + y - size.height ;
  434.             size.flags |= USPosition ;
  435.             size.y = y ;
  436.         }      
  437.     }
  438.  
  439.   frame = XCreateSimpleWindow(dpy, RootWindow(dpy, screen),
  440.                               size.x, size.y, size.width, size.height,
  441.                               CALCTOOL_BORDER_WIDTH, foregnd, backgnd) ;
  442.  
  443.   rframe = XCreateSimpleWindow(dpy, RootWindow(dpy, screen),
  444.                                size.x + TWIDTH + 15, size.y,
  445.                                size.width, 200,
  446.                                CALCTOOL_BORDER_WIDTH, foregnd, backgnd) ;
  447.  
  448.   protocol_atom = XInternAtom(dpy, "WM_PROTOCOLS", False) ;
  449.   kill_atom = XInternAtom(dpy, "WM_DELETE_WINDOW", False) ;
  450.  
  451.   XSetStandardProperties(dpy, frame, "calctool", NULL, calctool_icon,
  452.                          argv, argc, &size) ;
  453.  
  454.   wm_hints.icon_x = ix ;
  455.   wm_hints.icon_y = iy ;
  456.   wm_hints.input = True ;
  457.   wm_hints.icon_pixmap = calctool_icon ;
  458.   wm_hints.flags = InputHint | IconPixmapHint ;
  459.   if (iconic)
  460.     {
  461.       wm_hints.initial_state = IconicState ;
  462.       wm_hints.flags |= StateHint ;
  463.     }
  464.   XSetWMHints(dpy, frame, &wm_hints) ;
  465.  
  466.   gc_mask = GCFont | GCForeground | GCBackground | GCGraphicsExposures ;
  467.   gc_val.font = nfont->fid ;
  468.   gc_val.foreground = foregnd ;
  469.   gc_val.background = backgnd ;
  470.   gc_val.graphics_exposures = False ;
  471.   gc = XCreateGC(dpy, RootWindow(dpy, screen), gc_mask, &gc_val) ;
  472.   XSetFunction(dpy, gc, GXcopy) ;
  473.  
  474.   main_cursor = XCreateFontCursor(dpy, XC_top_left_arrow) ;
  475.   FGcolor.red = FGcolor.green = FGcolor.blue = 0 ;
  476.   BGcolor.red = BGcolor.green = BGcolor.blue = 0xffff ;
  477.   help_cursor = load_cursor(help_cursor_array) ;
  478. }
  479.  
  480.  
  481. make_icon() {}        /* Null routine - icon created in make_frame. */
  482.  
  483.  
  484. make_items()
  485. {
  486.   XSelectInput(dpy, frame, FRAME_MASK) ;
  487.   XMapWindow(dpy, frame) ;
  488.  
  489.   XSelectInput(dpy, rframe, ExposureMask) ;
  490. }
  491.  
  492.  
  493. make_subframes() {}          /* Null routine, see the make_frame routine. */
  494.  
  495. process_expose(event)
  496. /* XExposeEvent *event ; */
  497.      XEvent *event ;        /* Changed ART 12 Jan 94 */
  498. {
  499.   int doframe, dorframe ;
  500.  
  501.   doframe = dorframe = 0 ;
  502.   do
  503.     {
  504.       if (event->xexpose.count == 0)        /* Changed ART 12 Jan 94 */
  505.         {
  506.                if (event->xexpose.window == frame) doframe++ ;
  507.           else if (event->xexpose.window == rframe) dorframe++ ;
  508.         }
  509.     }
  510.   while (XCheckMaskEvent(dpy, ExposureMask, event)) ;
  511.  
  512.   if (dorframe && rstate) make_registers() ;
  513.   if (doframe) return(CFRAME_REPAINT) ;
  514. }
  515.  
  516. set_cursor(type)
  517. int type ;
  518. {
  519.   switch (type)
  520.     {
  521.       case HELPCURSOR : XDefineCursor(dpy, frame, help_cursor) ;
  522.                         break ;
  523.       case MAINCURSOR : XDefineCursor(dpy, frame, main_cursor) ;
  524.     }
  525. }
  526.  
  527.  
  528. start_tool()
  529. {
  530.   while (1)
  531.     process_event(get_next_event()) ;
  532. }
  533.  
  534.  
  535. toggle_reg_canvas()
  536. {
  537.   rstate = !rstate ;
  538.   if (rstate) XMapWindow(dpy, rframe) ;
  539.   else XUnmapWindow(dpy, rframe) ;
  540. }
  541.